(function () {
    return {
        compile: function (fnGetCompiler,doc, entities) {
            var me = this;
            var coderMaker = {
                make: function () {
                    return {
                        codes: [],
                        add: function (str) {
                            this.codes.push(str);
                        },
                        gen: function (split) {
                            return this.codes.join(split);
                        }
                    }
                }

            };
            var compileContext = {
                compile: function (entity) {
                    me._compileEntity(this, doc,entity);
                },
                fnGetCompiler: fnGetCompiler,
                dataNames: [],
                dataCoder: coderMaker.make(),//数据
                methodCoder: coderMaker.make(), //扩展方法
                templateCoder: coderMaker.make(), //扩展方法
                styleCoder: coderMaker.make(), //扩展方法
                onLoadCoder: coderMaker.make(), //预定义事件
                onUnloadCoder: coderMaker.make(), //预定义事件
                onDataChangeCoder: coderMaker.make(), //预定义事件
                eventCoder: coderMaker.make(), //所有的自定义事件
                idIndex:0,
                newID(){
                    this.idIndex++;
                    return this.idIndex;
                },
                findDataName:function(doc,dataid){
                    var dataName="";
                    $.each(doc.getAllData(), function (d) {
                        if ($.toInt(d.id) === $.toInt(dataid)) {
                            dataName = d.name;
                            return true;
                        }
                    });
                    return dataName;
                },
                gen: function () {
                    var me = this;
                    var arr = [];
                    arr.push("<script>$.vm({");
                    arr.push("data:{");
                    arr.push("appid:0,");
                    arr.push("jobid:0,");
                    arr.push("job:null,");
                    arr.push("ready:false,");

                    var names = {};
                    var nameArr = [];
                    $.each(me.dataNames, function (n) {
                        names[n] = 0
                    });
                    $.each(names, function (v,n) {
                        nameArr.push(n);
                        arr.push("\"" + n + "\":{},");
                    });
                    arr.push(me.dataCoder.gen(","));
                    arr.push("},");
                    arr.push("event:{");
                    arr.push("onLoad:function(){var me = this;");
                    arr.push("$.api(\"workflow.Task.GetDataVar\",{appid:me.appid,jobid:me.jobid,names:\"" +
                        nameArr.join("|") +
                        "\"}).then(function(value){" +
                        "$.each(value,function(v,k){me[k]=v;});" +
                        "me.ready=true;"+
                        "me.update();"+
                        "},function(err){});");
                    arr.push("if($.toInt(me.jobid)){" +
                        "$.api(\"workflow.Job.LoadBase\",{id:me.jobid}).then(function(value){" +
                        "me.job=value;"+
                        "})" +
                        "}");

                    arr.push(me.onLoadCoder.gen("\n"));
                    arr.push("},");
                    arr.push("onUnload:function(){var me = this;");
                    arr.push(me.onUnloadCoder.gen("\n"));
                    arr.push("},");
                    arr.push("onDataChange:function(){var me = this;");
                    arr.push(me.onDataChangeCoder.gen("\n"));
                    arr.push("},");
                    arr.push(me.eventCoder.gen(","));
                    arr.push("},");
                    arr.push(me.methodCoder.gen(","));
                    arr.push("});</script>");
                    arr.push("<style>" + me.styleCoder.gen("") + "</style>");
                    arr.push("<page-template><if cond='ready'>" + me.templateCoder.gen("") + "</if></page-template>");
                    return arr.join("");
                }
            };
            $.each(entities, function (entity) {
                me._compileEntity(compileContext,doc, entity)
            });
            return compileContext.gen();
        },
        _compileEntity: function (compileContext, doc,entity) {
            var compiler = compileContext.fnGetCompiler(entity.key);
            compiler.compile(compileContext, doc, entity);
        }
    }
})();